Tegra: introduce per-soc system reset handler
authorVarun Wadekar <[email protected]>
Tue, 10 Nov 2015 01:39:28 +0000 (17:39 -0800)
committerVarun Wadekar <[email protected]>
Tue, 10 Nov 2015 17:25:28 +0000 (09:25 -0800)
This patch adds a per-soc system reset handler for Tegra chips. The
handler gets executed before the actual system resets. This allows
for custom handling of the system reset sequence on each SoC.

Signed-off-by: Varun Wadekar <[email protected]>
plat/nvidia/tegra/common/tegra_pm.c
plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
plat/nvidia/tegra/soc/t210/plat_psci_handlers.c

index 87f72403c849209a16a9dc856e7dd8e51c8cba8b..c2c73f63063f3076f500855fdd21850e468c7d0d 100644 (file)
@@ -55,6 +55,7 @@ static int system_suspended;
 #pragma weak tegra_soc_prepare_cpu_on
 #pragma weak tegra_soc_prepare_cpu_off
 #pragma weak tegra_soc_prepare_cpu_on_finish
+#pragma weak tegra_soc_prepare_system_reset
 
 int tegra_soc_prepare_cpu_suspend(unsigned int id, unsigned int afflvl)
 {
@@ -76,6 +77,11 @@ int tegra_soc_prepare_cpu_on_finish(unsigned long mpidr)
        return PSCI_E_SUCCESS;
 }
 
+int tegra_soc_prepare_system_reset(void)
+{
+       return PSCI_E_SUCCESS;
+}
+
 /*******************************************************************************
  * Track system suspend entry.
  ******************************************************************************/
@@ -298,6 +304,9 @@ __dead2 void tegra_system_off(void)
  ******************************************************************************/
 __dead2 void tegra_system_reset(void)
 {
+       /* per-SoC system reset handler */
+       tegra_soc_prepare_system_reset();
+
        /*
         * Program the PMC in order to restart the system.
         */
index 79e9f1c507c867148e38c36e83fb834625afda49..46e594096ff7c6853cd2b3cae55aa6d4ccc8fc9c 100644 (file)
@@ -33,6 +33,7 @@
 #include <assert.h>
 #include <denver.h>
 #include <debug.h>
+#include <delay_timer.h>
 #include <flowctrl.h>
 #include <mmio.h>
 #include <platform_def.h>
 #define CPU_CMPLX_RESET_CLR            0x344
 #define CPU_CORE_RESET_MASK            0x10001
 
+/* Clock and Reset controller registers for system clock's settings */
+#define SCLK_RATE                      0x30
+#define SCLK_BURST_POLICY              0x28
+#define SCLK_BURST_POLICY_DEFAULT      0x10000000
+
 static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
 
 int32_t tegra_soc_validate_power_state(unsigned int power_state)
@@ -121,3 +127,19 @@ int tegra_soc_prepare_cpu_suspend(unsigned int id, unsigned int afflvl)
 
        return PSCI_E_SUCCESS;
 }
+
+int tegra_soc_prepare_system_reset(void)
+{
+       /*
+        * Set System Clock (SCLK) to POR default so that the clock source
+        * for the PMC APB clock would not be changed due to system reset.
+        */
+       mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
+                      SCLK_BURST_POLICY_DEFAULT);
+       mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
+
+       /* Wait 1 ms to make sure clock source/device logic is stabilized. */
+       mdelay(1);
+
+       return PSCI_E_SUCCESS;
+}
index 57be34762c2fc49e839ac8de807e46de62b38138..73358d4d4ca0adf93406df2dbb742643ac7fa371 100644 (file)
@@ -31,6 +31,7 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <debug.h>
+#include <delay_timer.h>
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
 #define CPU_CMPLX_RESET_CLR            0x454
 #define CPU_CORE_RESET_MASK            0x10001
 
+/* Clock and Reset controller registers for system clock's settings */
+#define SCLK_RATE                      0x30
+#define SCLK_BURST_POLICY              0x28
+#define SCLK_BURST_POLICY_DEFAULT      0x10000000
+
 static int cpu_powergate_mask[PLATFORM_MAX_CPUS_PER_CLUSTER];
 
 int32_t tegra_soc_validate_power_state(unsigned int power_state)
@@ -183,3 +189,19 @@ int tegra_soc_prepare_cpu_off(unsigned long mpidr)
        tegra_fc_cpu_off(mpidr & MPIDR_CPU_MASK);
        return PSCI_E_SUCCESS;
 }
+
+int tegra_soc_prepare_system_reset(void)
+{
+       /*
+        * Set System Clock (SCLK) to POR default so that the clock source
+        * for the PMC APB clock would not be changed due to system reset.
+        */
+       mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_BURST_POLICY,
+                      SCLK_BURST_POLICY_DEFAULT);
+       mmio_write_32((uintptr_t)TEGRA_CAR_RESET_BASE + SCLK_RATE, 0);
+
+       /* Wait 1 ms to make sure clock source/device logic is stabilized. */
+       mdelay(1);
+
+       return PSCI_E_SUCCESS;
+}